package lab.anoper.juc.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 闫家洪（yanjiahong@vcredit.com）
 * @since 2024/12/12
 */
public class OddEvenPrint {
    private static final int MAX_NUMBER = 100;

    private final ReentrantLock lock = new ReentrantLock(true);
    private final Condition oddCnd = lock.newCondition();
    private final Condition evenCnd = lock.newCondition();

    private int curNumber = 1;

    public void printOdd() throws Exception {
        while (curNumber < MAX_NUMBER) {
            lock.lock();
            try {
                if (curNumber % 2 == 1) {
                    System.out.println(curNumber);
                    curNumber++;
                    evenCnd.signal();
                } else {
                    oddCnd.await();
                }
            } finally {
                lock.unlock();
            }
        }
    }

    public void printEven() throws Exception {
        while (curNumber < MAX_NUMBER) {
            lock.lock();
            try {
                if (curNumber % 2 == 0) {
                    System.out.println(curNumber);
                    curNumber++;
                    oddCnd.signal();
                } else {
                    evenCnd.await();
                }
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        OddEvenPrint oddEvenPrint = new OddEvenPrint();
        new Thread(() -> {
            try {
                oddEvenPrint.printOdd();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(() -> {
            try {
                oddEvenPrint.printEven();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();
    }

}
















